package org.folio.rest.impl;

import io.vertx.core.AsyncResult;
import io.vertx.core.Context;
import io.vertx.core.Handler;
import org.apache.http.HttpStatus;
import org.folio.rest.impl.other.client.impl.OkapiUserModulesClientImpl;
import org.folio.rest.jaxrs.model.PartyUsersGetOrder;
import org.folio.rest.jaxrs.model.User;
import org.folio.rest.jaxrs.resource.PartyUsers;

import javax.ws.rs.BadRequestException;
import javax.ws.rs.core.Response;
import java.util.List;
import java.util.Map;

import static io.vertx.core.Future.failedFuture;
import static io.vertx.core.Future.succeededFuture;

/**
 * @author lee
 * @Classname PartyUserImpl
 * @Description TODO
 * @Date 2020/6/23 14:11
 * @Created by lee
 */
public class PartyUserImpl implements PartyUsers {
    /**
     * Retrieve a list of user items.
     *
     * @param query              A query expressed as a CQL string
     *                           (see [dev.folio.org/reference/glossary#cql](https://dev.folio.org/reference/glossary#cql))
     *                           using valid searchable fields.
     *                           The first example below shows the general form of a full CQL query,
     *                           but those fields might not be relevant in this context.
     * @param orderBy            Order by field: field A, field B
     * @param order              Order
     *                           default value: "desc"
     * @param offset             Skip over a number of elements by specifying an offset value for the query
     *                           default value: "0"
     *                           minimum value: "0.0"
     *                           maximum value: "2.147483647E9"
     * @param limit              Limit the number of elements returned in the response
     *                           default value: "10"
     *                           minimum value: "0.0"
     *                           maximum value: "2.147483647E9"
     * @param facets             facets to return in the collection result set, can be suffixed by a count of facet values to return, for example, patronGroup:10 default to top 5 facet values
     * @param lang               Requested language. Optional. [lang=en]
     *                           <p>
     *                           default value: "en"
     *                           pattern: "[a-zA-Z]{2}"
     * @param okapiHeaders
     * @param asyncResultHandler An AsyncResult<Response> Handler  {@link Handler} which must be called as follows - Note the 'GetPatronsResponse' should be replaced with '[nameOfYourFunction]Response': (example only) <code>asyncResultHandler.handle(io.vertx.core.Future.succeededFuture(GetPatronsResponse.withJsonOK( new ObjectMapper().readValue(reply.result().body().toString(), Patron.class))));</code> in the final callback (most internal callback) of the function.
     * @param vertxContext       The Vertx Context Object <code>io.vertx.core.Context</code>
     */
    @Override
    public void getPartyUsers(String query, String orderBy, PartyUsersGetOrder order, int offset, int limit, List<String> facets, String lang, Map<String, String> okapiHeaders, Handler<AsyncResult<Response>> asyncResultHandler, Context vertxContext) {
        OkapiUserModulesClientImpl okapiUserModulesClient = new OkapiUserModulesClientImpl(vertxContext.owner(), okapiHeaders);
        okapiUserModulesClient.getUserGroup(query).setHandler(
                event -> {
                    if (event.succeeded())
                    {
                        asyncResultHandler.handle(succeededFuture(GetPartyUsersResponse.respond200WithApplicationJson(event.result())));
                    } else if (event.cause().getClass() == BadRequestException.class) {
                        asyncResultHandler.handle(succeededFuture(
                                GetPartyUsersResponse.respond400WithTextPlain(event.cause().getMessage())));
                    } else {
                        asyncResultHandler.handle(succeededFuture(GetPartyUsersResponse.respond500WithTextPlain(event.cause())));
                    }
                }
        );
    }

    @Override
    public void postPartyUsers(String lang, User entity, Map<String, String> okapiHeaders, Handler<AsyncResult<Response>> asyncResultHandler, Context vertxContext) {
        OkapiUserModulesClientImpl okapiUserModulesClient = new OkapiUserModulesClientImpl(vertxContext.owner(), okapiHeaders);
        okapiUserModulesClient.updateUser(entity,reply->{
            if (reply.result().isOk() && reply.result().getStatus() == HttpStatus.SC_NO_CONTENT)
            asyncResultHandler.handle(succeededFuture(PostPartyUsersResponse.respond201WithApplicationJson(entity,PostPartyUsersResponse.headersFor201())));
            else
            asyncResultHandler.handle(succeededFuture(PostPartyUsersResponse.respond400WithTextPlain(reply.result().body())));
        });
    }


}
